package com.yanqu.road.dao.impl.player;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.impl.TempDataObjectDao;
import com.yanqu.road.entity.player.UserHistoryAttribute;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class UserHistoryAttributeDaoImpl extends TempDataObjectDao<UserHistoryAttribute> {

	public long getAllHistoryByLoginUser(long time) {
		String sql = "select sum(ability + 0) as allAbility from t_u_history_attribute where userId in (select userId from t_u_user where lastLoginTime >= ?)";
		ResultSet rs = null;
		CallableStatement call = null;
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareCall(sql);
			call.setLong(1, time);
			rs = call.executeQuery();
			while (rs.next()) {
				return rs.getLong("allAbility");
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return 0;
	}

	public UserHistoryAttribute getUserHistoryAttribute(long userId) {
		String sql = "select * from t_u_history_attribute where userId=?";
		ResultSet rs = null;
		CallableStatement call = null;
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareCall(sql);
			call.setLong(1, userId);
			rs = call.executeQuery();
			while (rs.next()) {
				UserHistoryAttribute data = parse(rs);
				return data;
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return null;
	}

	public Map<Long, UserHistoryAttribute> getUserHistoryAttributeMap(List<Long> userId) {
		String sql = "select * from t_u_history_attribute where userId in(" + StringUtils.listToString(userId, ",") + ")";
		ResultSet rs = null;
		CallableStatement call = null;
		Map<Long, UserHistoryAttribute> map = new ConcurrentHashMap<>();
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareCall(sql);
			rs = call.executeQuery();
			while (rs.next()) {
				UserHistoryAttribute data = parse(rs);
				map.put(data.getUserId(), data);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return map;
	}

	public List<UserHistoryAttribute> getUserHistoryAbilitys(int rankNum) {
		String sql = "select * from t_u_history_attribute order by ability+0 desc limit ?";
		List<UserHistoryAttribute> list = new ArrayList<>();
		ResultSet rs = null;
		CallableStatement call = null;
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareCall(sql);
			call.setInt(1, rankNum);
			rs = call.executeQuery();
			while (rs.next()) {
				UserHistoryAttribute data = parse(rs);
				list.add(data);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			getDb().closeConnection(call, rs);
		}
		return list;
	}


	@Override
	protected boolean addData(UserHistoryAttribute data) {
		PreparedStatement call = null;
		String sql = "INSERT INTO t_u_history_attribute(userId,ability,earnSpeed,activityStartAbility,activityStartEarnSpeed,rankActivityTopThreeTotalTimesData,crossRankActivityTopThreeTotalTimesData,"
				+ "qualification,activityStartQualification,crossActivityStartAbility,crossActivityStartEarnSpeed,crossActivityStartQualification,"
				+ "topBuildingEarnSpeed,musicRoomTimerAmountReward,musicRoomGuide) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareStatement(sql);
			int i = 1;
			call.setLong(i++, data.getUserId());
			call.setString(i++, data.getAbility().toString());
			call.setString(i++, data.getEarnSpeed().toString());
			call.setString(i++, data.getActivityStartAbility().toString());
			call.setString(i++, data.getActivityStartEarnSpeed().toString());
			call.setString(i++, data.getRankActivityTopThreeTotalTimesMapJson());
			call.setString(i++, data.getCrossRankActivityTopThreeTotalTimesMapJson());
			call.setLong(i++, data.getQualification());
			call.setLong(i++, data.getActivityStartQualification());
			call.setString(i++, data.getCrossActivityStartAbility().toString());
			call.setString(i++, data.getCrossActivityStartEarnSpeed().toString());
			call.setLong(i++, data.getCrossActivityStartQualification());
			call.setString(i++, data.getTopBuildingEarnSpeed().toString());
			call.setString(i++, PropertyHelper.parsePropertyToString(data.getMusicRoomTimerAmountReward()));
			call.setString(i++, data.getMusicRoomGuide());
			return call.executeUpdate() > 0;
		} catch (Exception e) {
			logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() + ":", e);
		} finally {
			getDb().closeConnection(call, null);
		}
		return false;
	}

	@Override
	protected boolean updateData(UserHistoryAttribute data) {
		PreparedStatement call = null;
		String sql = "UPDATE t_u_history_attribute SET ability=?,earnSpeed=?,activityStartAbility=?,activityStartEarnSpeed=?,rankActivityTopThreeTotalTimesData=?,crossRankActivityTopThreeTotalTimesData=?,"
				+ "qualification=?,activityStartQualification=?,crossActivityStartAbility=?,crossActivityStartEarnSpeed=?,crossActivityStartQualification=?,"
				+ "topBuildingEarnSpeed=?,musicRoomTimerAmountReward=?,musicRoomGuide=? WHERE userId=?";
		try {
			getDb().setConnName(DbNameStrategy.getUserDb());
			call = getDb().getConnection().prepareStatement(sql);
			int i = 1;
			call.setString(i++, data.getAbility().toString());
			call.setString(i++, data.getEarnSpeed().toString());
			call.setString(i++, data.getActivityStartAbility().toString());
			call.setString(i++, data.getActivityStartEarnSpeed().toString());
			call.setString(i++, data.getRankActivityTopThreeTotalTimesMapJson());
			call.setString(i++, data.getCrossRankActivityTopThreeTotalTimesMapJson());
			call.setLong(i++, data.getQualification());
			call.setLong(i++, data.getActivityStartQualification());
			call.setString(i++, data.getCrossActivityStartAbility().toString());
			call.setString(i++, data.getCrossActivityStartEarnSpeed().toString());
			call.setLong(i++, data.getCrossActivityStartQualification());
			call.setString(i++, data.getTopBuildingEarnSpeed().toString());
			call.setString(i++, PropertyHelper.parsePropertyToString(data.getMusicRoomTimerAmountReward()));
			call.setString(i++, data.getMusicRoomGuide());

			call.setLong(i++, data.getUserId());
			return call.executeUpdate() > 0;
		} catch (Exception e) {
			logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() + ":", e);
		} finally {
			getDb().closeConnection(call, null);
		}
		return false;
	}

	@Override
	protected UserHistoryAttribute parseData(ResultSet rs) throws SQLException {
		UserHistoryAttribute data = new UserHistoryAttribute();
		data.setUserId(rs.getLong("userId"));
		data.setQualification(rs.getLong("qualification"));
		data.setActivityStartQualification(rs.getLong("activityStartQualification"));
		data.setCrossActivityStartQualification(rs.getLong("crossActivityStartQualification"));
		String value = rs.getString("ability");
		if(!StringUtils.isNullOrEmpty(value)) {
			data.setAbility(new BigInteger(value));
		}
		value = rs.getString("earnSpeed");
		if(!StringUtils.isNullOrEmpty(value)) {
			data.setEarnSpeed(new BigInteger(value));
		}
		value = rs.getString("activityStartAbility");
		if(!StringUtils.isNullOrEmpty(value)) {
			data.setActivityStartAbility(new BigInteger(value));
		}
		value = rs.getString("activityStartEarnSpeed");
		if(!StringUtils.isNullOrEmpty(value)) {
			data.setActivityStartEarnSpeed(new BigInteger(value));
		}
		//
		value = rs.getString("crossActivityStartEarnSpeed");
		if(!StringUtils.isNullOrEmpty(value)) {
			data.setCrossActivityStartEarnSpeed(new BigInteger(value));
		}
		value = rs.getString("crossActivityStartAbility");
		if(!StringUtils.isNullOrEmpty(value)) {
			data.setCrossActivityStartAbility(new BigInteger(value));
		}
		String topThreeTimesData = rs.getString("rankActivityTopThreeTotalTimesData");
		Map<Integer, Integer> topThreeTimesMap;
		if(StringUtils.isNullOrEmpty(topThreeTimesData)){
			topThreeTimesMap = new ConcurrentHashMap<>();
		}else {
			topThreeTimesMap = JSON.parseObject(topThreeTimesData, new TypeReference<Map<Integer, Integer>>() {});
		}
		data.setRankActivityTopThreeTotalTimesMap(topThreeTimesMap);

		topThreeTimesData = rs.getString("crossRankActivityTopThreeTotalTimesData");
		Map<Integer, Integer> crossTopThreeTimesMap;
		if(StringUtils.isNullOrEmpty(topThreeTimesData)){
			crossTopThreeTimesMap = new ConcurrentHashMap<>();
		}else {
			crossTopThreeTimesMap = JSON.parseObject(topThreeTimesData, new TypeReference<Map<Integer, Integer>>() {});
		}
		data.setCrossRankActivityTopThreeTotalTimesMap(crossTopThreeTimesMap);

		value = rs.getString("topBuildingEarnSpeed");
		if(!StringUtils.isNullOrEmpty(value)){
			data.setTopBuildingEarnSpeed(new BigInteger(value));
		}
		value = rs.getString("musicRoomTimerAmountReward");
		if (!StringUtils.isNullOrEmpty(value)) {
			data.setMusicRoomTimerAmountReward(PropertyHelper.parseStringToProperty(value));
		}
		value = rs.getString("musicRoomGuide");
		if (!StringUtils.isNullOrEmpty(value)) {
			data.setMusicRoomGuide(value);
		}
		return data;
	}
}
